﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace iTunesUpdater
{
	class Transcoder
	{
		public delegate void LogEvent(Transcoder sender, string message);
		public event LogEvent logMessage;

		public Transcoder() {
		}

		private void log(string message) {
			if (logMessage != null)
				logMessage(this, message);
		}


		/// <summary>
		/// Source folder for transcode operations. You can watch multiple folders, separate
		/// multiple folders with a semicolon (;).
		/// </summary>
		public static string SourcePath = @"C:\Recorded TV;C:\video";
		/// <summary>
		/// File types to transcode. Use filename wildcards (*.ext) and separate with semicolons.
		/// </summary>
		public static string SourceFilter = @"*.mpg;*.ms-divr;*.avi";
		/// <summary>
		/// folder to save output files. You cannot set multiple output folders.
		/// </summary>
		public static string Destpath = @"C:\temp";
		/// <summary>
		/// The watch file tells the program that a file is being transcoded, even if the 
		/// program has stopped or if you're running multiple instances. The watch file is
		/// a file named "transcode.txt" in the output folder.
		/// </summary>
		/// <returns></returns>
		public static string WatchFileName {
			get {
				return System.IO.Path.Combine(Destpath, "transcode.txt");
			}
		}

		/// <summary>
		/// Check to see whether a file is being transcoded.
		/// </summary>
		/// <returns>True if a transcode operation is in progress</returns>
		public static bool isTranscodeActive {
			get {
				string filename = WatchFileName;
				if (System.IO.File.Exists(filename))
					return true;
				else
					return false;
			}
		}

		static string getDestFilename(string SourceFileName) {
			string dest;
			dest = System.IO.Path.GetFileName(SourceFileName);
			dest = System.IO.Path.ChangeExtension(dest, ".mp4");
			dest = System.IO.Path.Combine(Destpath, dest);
			return dest;
		}

		/// <summary>
		/// Sets a monitor file that says a transcode is in progress. No new transcoding will
		/// happen if this file exists. To clear the monitor file
		/// and enable transcoding, call with an empty parameter. 
		/// </summary>
		/// <param name="FileBeingTranscoded">Name of the file being transcoded. 
		/// Blank to clear and enable new transcode operations.</param>
		public static void SetTranscodeActive(string FileBeingTranscoded) {
			if (FileBeingTranscoded != "") {
				System.IO.StreamWriter fs = new StreamWriter(WatchFileName);
				fs.WriteLine(getDestFilename(FileBeingTranscoded));
				fs.Close();
			}
			else
				SetTranscodeFinished();
		}

		public static void SetTranscodeFinished() {
			File.Delete(WatchFileName);
		}

		public void TranscodeFile(string FileName) {
			log("Trancoding " + FileName);

			string dest = getDestFilename(FileName);

			System.Diagnostics.Process proc = new System.Diagnostics.Process();
			proc.EnableRaisingEvents = false;
			proc.StartInfo.FileName = "transcode.bat";
			proc.StartInfo.Arguments = "\"" + FileName + "\" \"" + dest + "\" \"" + Transcoder.WatchFileName;
			//proc.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Minimized;
			proc.Start();
			try {
				proc.PriorityClass = System.Diagnostics.ProcessPriorityClass.Idle;
			}
			catch (Exception ex) {
				System.Diagnostics.Debug.WriteLine(ex.Message);
			}
		}

		public void TranscodeFolder(string folder, string filter) {
			System.Diagnostics.Debug.WriteLine("Folder " + folder);
			string[] files = System.IO.Directory.GetFiles(folder, filter, System.IO.SearchOption.AllDirectories);

			// we're only going to transcode one file. So when we find the first file with the archive bit set, 
			// start the Transcoder.
			foreach (string file in files) {
				FileInfo fi = new System.IO.FileInfo(file);
				FileAttributes fa = fi.Attributes;
				// if the archive bit is set, but it's not hidden, transcode it.
				// BTV hides files that are actively being recorded (convenient, eh?) 
				if (((fa & FileAttributes.Archive) == FileAttributes.Archive)
						&& ((fa & FileAttributes.Hidden) == 0)) {
					SetTranscodeActive(file);
					TranscodeFile(file);
					break;
				}
			}
		}

		public void TranscodeAll() {
			foreach (string folder in SourcePath.Split(';')) {
				foreach (string filter in SourceFilter.Split(';')) {
          if (isTranscodeActive)
            return;
          TranscodeFolder(folder, filter);
				}
			}
		}

		public static string CurrentFile {
			get {
				if (File.Exists(WatchFileName)) {
					StreamReader reader = new StreamReader(WatchFileName);
					string fileName = reader.ReadLine();
					reader.Close();
					return Path.GetFileName(fileName);
				}
				return "";
			}
		}

	}
}
